from Config.myConstant import *
from Config.myConfig import *
from DataAccess.TradedayDataProcess import TradedayDataProcess
from DataPrepare.tickFactorsProcess import tickFactorsProcess
from DataAccess.KLineDataProcess import KLineDataProcess
from DataPrepare.dailyFactorsProcess import dailyFactorsProcess
from Utility.JobLibUtility import JobLibUtility
from Strategy.baseStrategy.baseStrategy import baseStrategy
import pandas as pd
import numpy as np
import math
import xgboost as xgb
import warnings
from DataAccess.TickDataProcess import TickDataProcess
from DataPrepare.tickFactors.tickDataPrepared import tickDataPrepared
from DataAccess.IndexComponentDataProcess import IndexComponentDataProcess
from Utility.InfluxdbUtility import InfluxdbUtility
from joblib import Parallel, delayed,parallel_backend

class strategy20200624():
    #----------------------------------------------------------------------
    def __init__(self):
        self.name='利用逐笔成交数据计算做市策略'
        pass
    def singleCode(self,code,startDate,endDate):
        startDate=str(startDate)
        endDate=str(endDate)
        days=list(TradedayDataProcess().getTradedays(startDate,endDate))
        tickdata=TickDataProcess()
        volume0=500000
        totalvolume=10000000
        initialvolume=10000000
        netvalue=[]
        for day in days:
            md=tickdata._TickDataProcess__getTickShotDataFromSqlServer(code,day)
            md=md[md['tick']>='093000000']
            td=tickdata._TickDataProcess__getTransactionDataFromSqlServer(code,day)
            mdindex={}
            tdindex={}
            mySell={}
            myBuy={}
           
            #bprice=md['B1'].iloc[0]
            #bvolume=md['BV1'].iloc[0]
            #sprice=md['S1'].iloc[0]
            #svolume=md['SV1'].iloc[0]
            #mySell={'price':sprice,'waitvolume':svolume,'myvolume':volume0,'dealvolume':0}
            #myBuy={'price':bprice,'waitvolume':bvolume,'myvolume':volume0,'dealvolume':0}
            transactionSell={}
            transactionBuy={}

            for item in md.columns:
                mdindex.update({item:list(md.columns).index(item)})
            
            for item in td.columns:
                tdindex.update({item:list(td.columns).index(item)})
            mdvalues=md.values
            tdvalues=td.values

            for i in range(len(mdvalues)-1):
                mdnow=mdvalues[i]
                mdnext=mdvalues[i+1]
                tick=mdnow[mdindex['tick']]
                nexttick=mdnext[mdindex['tick']]
                transaction={}
                for tdrows in range(len(tdvalues)):
                    tdnow=tdvalues[tdrows]
                    tdticknow=tdnow[tdindex['tick']]
                    if ((tdticknow>=tick) and (tdticknow<nexttick)):
                        price=tdnow[tdindex['price']]
                        volume=tdnow[tdindex['volume']]
                        if (price in transaction.keys()):
                            transaction[price]+=volume
                        else:
                            transaction.update({price:volume})

                        buyorsell=tdnow[tdindex['functionCode']]
                        #print(f"index: {tdrows} {tdticknow}  price {price} volume {volume} buyorsell {buyorsell}")
                    else:
                        if (tdticknow>=nexttick):
                            break
                sprice=mdnow[mdindex['S1']]
                bprice=mdnow[mdindex['B1']]
                marketvolume=0
                marketamount=0
                marketprice=(sprice+bprice)/2
                for k,v in transaction.items():
                    marketvolume+=v
                    marketamount+=k*v
                if (marketvolume>0):
                    marketprice=marketamount/marketvolume

                
                #print(transaction)
                print(f"{tick}-->{nexttick} S1:{sprice} b1:{bprice} marketPrice:{marketprice}")
                ####################################################################################
                #判断是否需要新挂单
                
                if (myBuy=={}) and (mySell=={}) and (tick<'145500000'):
                    #新挂单
                    buyvolume=0
                    for k,v in transactionBuy.items():
                        buyvolume+=v
                    #totalvolume=initialvolume-buyvolume
                    totalvolume=min(volume0,initialvolume-buyvolume)
                    sprice=mdnow[mdindex['S1']]
                    svolume=mdnow[mdindex['SV1']]
                    bprice=mdnow[mdindex['B1']]
                    bvolume=mdnow[mdindex['BV1']]
                    if (abs(sprice-bprice)<=0.015) and (min(svolume,bvolume)>10*volume0) and (max(svolume,bvolume)/min(svolume,bvolume)<2):
                        mySell={'price':sprice,'waitvolume':svolume,'myvolume':totalvolume,'dealvolume':0}
                        myBuy={'price':bprice,'waitvolume':bvolume,'myvolume':totalvolume,'dealvolume':0}
                    pass
                ####################################################################################
                #计算当前盘口，判断是否需要撤单
                if (myBuy!={}) and (mySell!={}):
                    deltavolume=myBuy['dealvolume']-mySell['dealvolume']
                    if (deltavolume==0):
                        sprice=mdnow[mdindex['S1']]
                        svolume=mdnow[mdindex['SV1']]
                        bprice=mdnow[mdindex['B1']]
                        bvolume=mdnow[mdindex['BV1']]
                        if ((min(svolume,bvolume)>0)and (max(svolume,bvolume)/min(svolume,bvolume)>=3)):
                            #撤单
                            if (myBuy['price'] in transactionBuy.keys()):
                                transactionBuy[myBuy['price']]+=myBuy['dealvolume']
                            else:
                                transactionBuy.update({myBuy['price']:myBuy['dealvolume']})

                            if (mySell['price'] in transactionSell.keys()):
                                transactionSell[mySell['price']]+=mySell['dealvolume']
                            else:
                                transactionSell.update({mySell['price']:mySell['dealvolume']})
                            myBuy={}
                            mySell={}
                        pass
                

                
                
                ####################################################################################
                #计算敞口，并判断是否需要平仓
                if (myBuy!={}) and (mySell!={}):
                    deltavolume=myBuy['dealvolume']-mySell['dealvolume']
                else:
                    deltavolume=0
                if (deltavolume>0.5*volume0):
                    price=mdnow[mdindex['B1']]
                    volume=mdnow[mdindex['BV1']]
                    if (price<myBuy['price'])or (tick>='145500000') or ((price==myBuy['price']) and (volume<10*volume0)):
                        #强制平仓
                        if (myBuy['price'] in transactionBuy.keys()):
                            transactionBuy[myBuy['price']]+=myBuy['dealvolume']
                        else:
                            transactionBuy.update({myBuy['price']:myBuy['dealvolume']})

                        if (mySell['price'] in transactionSell.keys()):
                            transactionSell[mySell['price']]+=mySell['dealvolume']
                        else:
                            transactionSell.update({mySell['price']:mySell['dealvolume']})

                        if (price in transactionSell.keys()):
                            transactionSell[price]+=deltavolume
                        else:
                            transactionSell.update({price:deltavolume})
                        myBuy={}
                        mySell={}
                    pass
                elif (deltavolume<-0.5*volume0):
                    price=mdnow[mdindex['S1']]
                    volume=mdnow[mdindex['SV1']]
                    if (price>mySell['price']) or (tick>='145500000') or ((price==mySell['price']) and (volume<10*(-volume0))):
                        #强制平仓
                        if (myBuy['price'] in transactionBuy.keys()):
                            transactionBuy[myBuy['price']]+=myBuy['dealvolume']
                        else:
                            transactionBuy.update({myBuy['price']:myBuy['dealvolume']})

                        if (mySell['price'] in transactionSell.keys()):
                            transactionSell[mySell['price']]+=mySell['dealvolume']
                        else:
                            transactionSell.update({mySell['price']:mySell['dealvolume']})
                        
                        if (price in transactionBuy.keys()):
                            transactionBuy[price]+=-deltavolume
                        else:  
                            transactionBuy.update({price:-deltavolume})
                        myBuy={}
                        mySell={}
                    pass
                    
                if (myBuy=={}) or (mySell=={}):
                    #print(transactionBuy)
                    #print(transactionSell)
                    #print("warning! There is no order now!")
                    continue
                if ((myBuy['dealvolume']==mySell['dealvolume']) and (myBuy['dealvolume']==volume0)):
                    if (myBuy['price'] in transactionBuy.keys()):
                            transactionBuy[myBuy['price']]+=myBuy['dealvolume']
                    else:
                        transactionBuy.update({myBuy['price']:myBuy['dealvolume']})

                    if (mySell['price'] in transactionSell.keys()):
                        transactionSell[mySell['price']]+=mySell['dealvolume']
                    else:
                        transactionSell.update({mySell['price']:mySell['dealvolume']})
                    myBuy={}
                    mySell={}
                    #print(transactionBuy)
                    #print(transactionSell)
                    #print("warning! There is no order now!")
                    continue
                for k in transactionBuy.keys():
                    if (k==0):
                        print("error!")
                for k in transactionSell.keys():
                    if (k==0):
                        print("error!")
                ####################################################################################
                #buy situation
                
                buy={}
                buynext={}
                buymodify={}
                for t in range(1,11):
                    price=mdnow[mdindex['B'+str(t)]]
                    volume=mdnow[mdindex['BV'+str(t)]]
                    buy.update({price:volume})
                    price=mdnext[mdindex['B'+str(t)]]
                    volume=mdnext[mdindex['BV'+str(t)]]
                    buynext.update({price:volume})
                for price in list(set(buy.keys()) & set(buynext.keys())):
                    if price in transaction.keys():
                        transactionvolume=transaction[price]
                    else:
                        transactionvolume=0
                    cancelvolume=max(0,buy[price]-buynext[price]-transactionvolume)
                    buymodify.update({price:transactionvolume+cancelvolume})
                    pass
                for price in list(set(buy.keys()).difference(set(buynext.keys()))):
                    if price in transaction.keys():
                        transactionvolume=transaction[price]
                    else:
                        transactionvolume=0
                    cancelvolume=max(0,buy[price]-transactionvolume)
                    buymodify.update({price:transactionvolume+cancelvolume})
                    pass
                price=myBuy['price']
                if ((price in transaction.keys()) and (myBuy['myvolume']>0)):
                    if (transaction[price]>myBuy['waitvolume']):
                        myBuy['waitvolume']=0
                        dealvolume=min(myBuy['myvolume'],transaction[price]-myBuy['waitvolume'])
                        myBuy['dealvolume']+=dealvolume
                        myBuy['myvolume']-=dealvolume
                    else:
                        if price in buymodify.keys():
                            myBuy['waitvolume']=max(0,myBuy['waitvolume']-buymodify[price])
                    pass
                    
                ####################################################################################
                #sell situation
                
                sell={}
                sellnext={}
                sellmodify={}
                for t in range(1,11):
                    price=mdnow[mdindex['S'+str(t)]]
                    volume=mdnow[mdindex['SV'+str(t)]]
                    sell.update({price:volume})
                    price=mdnext[mdindex['S'+str(t)]]
                    volume=mdnext[mdindex['SV'+str(t)]]
                    sellnext.update({price:volume})
                for price in list(set(sell.keys()) & set(sellnext.keys())):
                    if price in transaction.keys():
                        transactionvolume=transaction[price]
                    else:
                        transactionvolume=0
                    cancelvolume=max(0,sell[price]-sellnext[price]-transactionvolume)
                    sellmodify.update({price:transactionvolume+cancelvolume})
                    pass
                for price in list(set(sell.keys()).difference(set(sellnext.keys()))):
                    if price in transaction.keys():
                        transactionvolume=transaction[price]
                    else:
                        transactionvolume=0
                    cancelvolume=max(0,sell[price]-transactionvolume)
                    sellmodify.update({price:transactionvolume+cancelvolume})
                    pass
                price=mySell['price']
                if ((price in transaction.keys()) and (mySell['myvolume']>0)):
                    if (transaction[price]>mySell['waitvolume']):
                        myBuy['waitvolume']=0
                        dealvolume=min(mySell['myvolume'],transaction[price]-mySell['waitvolume'])
                        mySell['dealvolume']+=dealvolume
                        mySell['myvolume']-=dealvolume
                    else:
                        if price in sellmodify.keys():
                            mySell['waitvolume']=max(0,mySell['waitvolume']-sellmodify[price])
                    pass
                ####################################################################################

                #print(myBuy)
                #print(mySell)

                pass
            buycash=0
            buyvolume=0
            for k,v in transactionBuy.items():
                buycash+=k*v
                buyvolume+=v
            sellcash=0
            sellvolume=0
            for k,v in transactionSell.items():
                sellcash+=k*v
                sellvolume+=v
            print(f"buyvolume:{buyvolume} buycash:{buycash}")
            print(f"sellvolume:{sellvolume} sellcash:{sellcash}")
            profit=sellcash-buycash-buycash*0.00009-sellcash*0.00109
            myyield=0
            if (buycash>0):
                print(f"day:{day} profit:{profit} amount:{buycash} rate:{profit/buycash}")
                myyield=profit/buycash
            netvalue.append({'date':day,'amount':buycash,'profit':profit,'yield':myyield})
            print(transactionSell)
            print(transactionBuy)


                
            pass
        netvalue=pd.DataFrame(netvalue)
        print(netvalue)
        print(netvalue['profit'].sum())
        print(netvalue['amount'].sum())

        pass
    pass



